﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using VntNet.PowerSchemeSwitcher.Properties;

namespace VntNet.PowerSchemeSwitcher
{
    public partial class SystemTryIcon : Component
    {
        ToolStripMenuItem _selectedMenuItem;
        Dictionary<Guid, PowerPlanInfo> _powerPlans;
        ToolStripMenuItem _menuExitItem;
        ToolStripMenuItem _menuAutoItem;
        
        internal event Action ShowSettingForm;
        internal event Action SettingChanged;

        string _currentPowerLineName;
        string _currentPowerSchemeName;

        public SystemTryIcon()
        {
            InitializeComponent();
        }

        public SystemTryIcon(IContainer container)
        {
            container.Add(this);
            InitializeComponent();
        }

        void OnShowSettingForm()
        {
            if (ShowSettingForm != null)
                ShowSettingForm();
        }

        void OnSettingChanged()
        {
            if (SettingChanged != null)
                SettingChanged();
        }

        internal void Show()
        {
            AddAutoMenuItem();
            AddPowerPlansAsMenuItems();
            AddExitMenuItem();
            notifyIcon.Icon = Resources.TypicalPowerIcon;
            notifyIcon.Visible = true;
        }

        internal void UpdateUiInfo(string currentPowerLineName, PowerSettingNotificationMsgFilter.PowerSavingLevelEnum currentPowerSavingLevel)
        {
            _currentPowerLineName = currentPowerLineName;                      
            UpdateIcon(currentPowerSavingLevel);
            UpdateUiInfo();
        }

        internal void UpdateUiInfo()
        {
            Guid ActiveSchemeGuid = PowerSchemeHelper.GetPowerActiveScheme();
            UpdatePowerPlansMenuItems();
            UpdateSelectedItem(ActiveSchemeGuid);
            UpdateToolTip();
        }


        private void UpdateIcon(PowerSettingNotificationMsgFilter.PowerSavingLevelEnum currentPowerSavingLevel)
        {
            switch (currentPowerSavingLevel)
            {
                case PowerSettingNotificationMsgFilter.PowerSavingLevelEnum.Max:
                    notifyIcon.Icon = Resources.MaxSavingIcon;
                    break;
                case PowerSettingNotificationMsgFilter.PowerSavingLevelEnum.Min:
                    notifyIcon.Icon = Resources.MaxPowerIcon;
                    break;
                case PowerSettingNotificationMsgFilter.PowerSavingLevelEnum.Typical:
                    notifyIcon.Icon = Resources.TypicalPowerIcon;
                    break;
                default:
                    notifyIcon.Icon = Resources.TypicalPowerIcon;
                    break;
            }
        }

        void UpdateToolTip()
        {
            notifyIcon.Text = String.Format("{0}{1}{2}", _currentPowerLineName, '-', _currentPowerSchemeName);
        }

        internal void ShowBalloonTip(int timeout, string tipTitle, string tipText, ToolTipIcon tipIcon)
        {
            notifyIcon.ShowBalloonTip(timeout, tipTitle, tipText, tipIcon);
        }
        #region TryIcon
       
        private void notifyIcon_DoubleClick(object sender, EventArgs e)
        {
            OnShowSettingForm();
        }

        private void notifyIcon_BalloonTipClicked(object sender, EventArgs e)
        {
            OnShowSettingForm();
        }

        #endregion

        #region Menu Items
        void menuItem_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
            PowerPlanInfo powerPlanInfo = menuItem.Tag as PowerPlanInfo;
            powerPlanInfo.Set();
            Settings.Default.EnableAutoSwitching = false;
            _menuAutoItem.Checked = false;

        }

        void menuExitItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        void AddAutoMenuItem()
        {
            _menuAutoItem = new ToolStripMenuItem("Auto");
            _menuAutoItem.Click += new EventHandler(_menuAutoItem_Click);
            this.systemTryContextMenuStrip.Items.Add(_menuAutoItem);
            this.systemTryContextMenuStrip.Items.Add(new ToolStripSeparator());
        }

        void _menuAutoItem_Click(object sender, EventArgs e)
        {
            _menuAutoItem.Checked = !_menuAutoItem.Checked;
            Settings.Default.EnableAutoSwitching = _menuAutoItem.Checked;
            OnSettingChanged();
        }

        void AddExitMenuItem()
        {
            this.systemTryContextMenuStrip.Items.Add(new ToolStripSeparator());
            _menuExitItem = new ToolStripMenuItem("Exit");
            _menuExitItem.Click += new EventHandler(menuExitItem_Click);
            this.systemTryContextMenuStrip.Items.Add(_menuExitItem );
        }
        /// <summary>
        /// See if it is necessary to add or remove power scheme menu items
        /// and eventually change the names
        /// </summary>
        void UpdatePowerPlansMenuItems()
        {           
            var CurrentPlanList = PowerSchemeHelper.GetAllPowerSchemas();
            //search for new palns
            foreach (var i in CurrentPlanList)
            {
                //new power scheme?
                if (!_powerPlans.ContainsKey(i.Key))
                {
                    AddMenuItem(i.Value);
                    _powerPlans.Add(i.Key, i.Value);
                }
                else
                {
                    //see if we chacnged the name
                    var tempPlan = _powerPlans[i.Key];
                    if (i.Value.FriendlyName != tempPlan.FriendlyName)
                    {
                        ((ToolStripMenuItem)tempPlan.Tag).Text = i.Value.FriendlyName;
                    }
                }
            }
            
            //search for deleted plans
            for (int i = _powerPlans.Count - 1; i >= 0; i--)
            {
                var p = _powerPlans.ElementAt(i);
                //detete old ones
                if (!CurrentPlanList.ContainsKey(p.Key))
                {                    
                    RemoveMenuItem(p.Value);
                    _powerPlans.Remove(p.Key);
                }
            }
            
        }

        /// <summary>
        /// Put a flag next to the correct menu item to shaw what plan is currently active
        /// </summary>
        /// <param name="activeSchemeGuid"></param>
        void UpdateSelectedItem(Guid activeSchemeGuid)
        {
            //update selected item and get the current name           
            foreach (var i in _powerPlans)
            {
                if (i.Key == activeSchemeGuid)
                {
                    CheckMenuItem((ToolStripMenuItem)i.Value.Tag);                    
                }
            }            
        }

        void AddPowerPlansAsMenuItems()
        {
            _powerPlans = PowerSchemeHelper.GetAllPowerSchemas();
            foreach (var p in _powerPlans)
            {
                AddMenuItem(p.Value);
            }
            //force a refresh
            PowerSchemeHelper.SetPowerScheme(PowerSchemeHelper.GetPowerActiveScheme());
        }

        void RemoveMenuItem(PowerPlanInfo powerPlanInfo)
        {
            ToolStripMenuItem menuItem = (ToolStripMenuItem)powerPlanInfo.Tag;
            this.systemTryContextMenuStrip.Items.Remove(menuItem);
        }

        void AddMenuItem(PowerPlanInfo powerPlanInfo)
        {
            //TODO: add items in aphabetical order
            ToolStripMenuItem menuItem = new ToolStripMenuItem(powerPlanInfo.FriendlyName);
            menuItem.Tag = powerPlanInfo;
            menuItem.Click += new EventHandler(menuItem_Click);
            powerPlanInfo.Tag = menuItem;
            if (_menuExitItem == null)
                this.systemTryContextMenuStrip.Items.Add(menuItem);
            else
            {
                //we want exit to be the last item (-2 because there is the saparator)
                this.systemTryContextMenuStrip.Items.Insert(systemTryContextMenuStrip.Items.Count - 2, menuItem);
            }
        }

        void CheckMenuItem(ToolStripMenuItem menuItem)
        {
            //unchek previus one
            if (_selectedMenuItem != null)
                _selectedMenuItem.Checked = false;
            //remember wich is the current selected item
            _selectedMenuItem = menuItem;
            //applay the change
            menuItem.Checked = true;
            _currentPowerSchemeName = menuItem.Text;
        }

        internal void UpdateMenuAutoItemStatus(bool enable)
        {
            _menuAutoItem.Enabled = enable;
            _menuAutoItem.Checked = Settings.Default.EnableAutoSwitching;
        }

     
        #endregion
    }
}
